package service

import (
	"context"
	"el/app/libs"
	"el/app/models"
	"el/app/models/request"
	"el/app/models/response"
	"el/bootstrap/driver"
	"errors"
	"time"

	"github.com/dgrijalva/jwt-go"
)

//登录
func Login(login *request.Login) (*response.Login, error) {
	admin := models.NewAdminUser()
	if isFrequently(login.Username) {
		return nil, errors.New("登录失败次数过多,请等待")
	}

	admin.Username = login.Username
	err := admin.InfoByUsername()
	if err != nil {
		addFrequently(login.Username)
		return nil, errors.New("用户名或密码错误")
	}

	if !libs.HashCompare(admin.Password, login.Password) {
		addFrequently(login.Username)
		return nil, errors.New("用户名或密码错误")
	}
	claims := &request.Claims{
		Id:       admin.Id,
		Username: admin.Username,
		StandardClaims: jwt.StandardClaims{
			NotBefore: time.Now().Unix() - 1000,
			ExpiresAt: time.Now().Unix() + 86400,
			Issuer:    "my",
		},
	}
	token, err := libs.CreateJwt(claims)
	if err != nil {
		return nil, err
	}
	return &response.Login{Token: token}, nil
}

//是否频繁登录
func isFrequently(username string) bool {
	str, err := driver.RedisDb.Get(context.Background(), libs.UserFrequentlyRedis+username).Result()

	if err != nil {
		return false
	}
	count := int(libs.StringToInt(str))
	return count >= libs.UserFrequentlyCount
}

//添加频繁登录缓存
func addFrequently(username string) {
	driver.RedisDb.IncrBy(context.Background(), libs.UserFrequentlyRedis+username, 1)
	driver.RedisDb.Expire(context.Background(), libs.UserFrequentlyRedis+username, time.Minute*libs.UserFrequentlyTime)
}

func Out(token string) error {
	userOut := libs.Md516(token)
	outRedis := libs.UserOutRedis + userOut
	_, err := driver.RedisDb.Set(context.Background(), outRedis, token, time.Hour*24).Result()
	return err
}

func InOutRedis(token string) bool {
	userOut := libs.Md516(token)
	outRedis := libs.UserOutRedis + userOut
	str, err := driver.RedisDb.Get(context.Background(), outRedis).Result()
	if err == nil && str == token {
		return true
	}
	return false
}

func Log(paginate request.Paginate, logSearch *request.LogSearch) (response.PageList, error) {
	admin_log := models.NewAdminLog()
	pageList, err := admin_log.List(paginate, logSearch)
	return pageList, err
}
